package com.renwen.sms.service.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.renwen.sms.dao.CourseDao;

import com.renwen.sms.dao.TeacherDao;

import com.renwen.sms.dto.CourseDto;
import com.renwen.sms.dto.PageResult;

import com.renwen.sms.entity.*;
import com.renwen.sms.exception.MyRuntimeException;
import com.renwen.sms.service.CourseService;
import com.renwen.sms.util.Result;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class CourseServiceImpl implements CourseService {
    @Resource
    CourseDao courseDao;
    @Resource
    TeacherDao teacherDao;

    /**
     * 分页查询所有课程信息
     *
     * @param page      页码
     * @param size      每页显示条数
     * @param searchMap 搜索条件
     * @return 课程表信息
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public PageResult<CourseDto> list(Integer page, Integer size, Map<String, Object> searchMap) {
        // 构建查询条件
        //搜索框模糊查询
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        QueryWrapper<Teacher> queryWrapper1 = new QueryWrapper<>();
        if (!ObjectUtil.hasEmpty(searchMap)) {
            if (!ObjectUtil.hasEmpty(searchMap.get("type"))) {
                queryWrapper.eq("type", searchMap.get("type"));
            }
            if (!ObjectUtil.hasEmpty(searchMap.get("name"))) {
                queryWrapper.like("c_name", searchMap.get("name"));
            }
        }
        queryWrapper.select("c_no", "c_name", "kind", "id", "type", "deng_ji");
        // 根据id降序排序
        queryWrapper.orderByDesc("id");
        Page<Course> courses = courseDao.selectPage(new Page<Course>(page, size), queryWrapper);
        List<CourseDto> cds = new ArrayList<>();
        CourseDto courseDto = new CourseDto();
        //遍历课程信息
        for (Course course : courses.getRecords()) {
            //根据课程号查询授课教师信息
            QueryWrapper<Teacher> c_no = queryWrapper1.eq("c_no", course.getCNo());
            Teacher teacher = teacherDao.selectOne(c_no);
            //存放课程信息对象
            //拷贝属性
            BeanUtils.copyProperties(course, courseDto);
            //判断当前是否安排了授课教师
            if (teacher != null) {
                courseDto.setTeacher(teacher.getTName());
            } else {
                courseDto.setTeacher("暂无");
            }
            //清空查询条件
            c_no.clear();
            //添加教师信息到数组
            cds.add(courseDto);
            //重新开辟内存地址
            courseDto = new CourseDto();
        }
        return new PageResult<CourseDto>(cds, courses.getTotal());
    }


    /**
     * 添加课程
     *
     * @param course
     */
    @Override
    public void save(Course course) {
        // 0. 验证课程号
        if (!ReUtil.isMatch("\\d{2,4}$", course.getCNo())) {
            throw new MyRuntimeException("课程号不对！");
        }
        // 1. 执行添加操作
        try {
            courseDao.insert(course);
        } catch (Exception e) {
            throw new MyRuntimeException("添加课程出错！" + e.getMessage());
        }
    }

    /**
     * 根据课程编号查询课程信息
     *
     * @param id 课程编号
     * @return 课程信息
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public Result get(Integer id) {
        if (!NumberUtil.isNumber(String.valueOf(id))) {
            throw new MyRuntimeException("编号应该是数字！");
        }
        try {
            Course course = courseDao.selectById(id);
            CourseDto courseDto = new CourseDto();
            BeanUtils.copyProperties(course, courseDto);
            return new Result("查询成功", courseDto);
        } catch (Exception e) {
            throw new MyRuntimeException("根据课程编号查询出错！" + e.getMessage());
        }
    }

    /**
     * 修改课程信息
     *
     * @param course 教师对象
     */
    @Override
    public void update(Course course) {
        // 0. 验证课程号
        if (!ReUtil.isMatch("\\d{2,4}$", course.getCNo())) {
            throw new MyRuntimeException("课程号格式不对！");
        }
        // 2. 执行修改操作
        try {
            courseDao.updateById(course);
        } catch (Exception e) {
            throw new MyRuntimeException("修改课程信息出错！" + e.getMessage());
        }
    }

    /**
     * 根据课程号删除
     */
    @Override
    public void delete(String cNo) {
        Map<String, Object> map = new HashMap<>();
        map.put("c_no", cNo);
        try {
            courseDao.deleteByMap(map);
        } catch (Exception e) {
            throw new MyRuntimeException("删除课程时出错！" + e.getMessage());
        }
    }

    /**
     * 批量删除课程信息
     *
     * @param ids 课程编号列表
     */
    @Override
    public void batchDelete(String ids) {
        //字符串切割
        String[] strs = ids.split(",");
        List<Integer> ids1 = new ArrayList<>();
        for (String str : strs) {
            ids1.add(Integer.valueOf(str));
        }
        if (ObjectUtil.hasEmpty(ids1)) {
            throw new MyRuntimeException("请先选择要删除的课程！");
        }
        try {
            courseDao.deleteBatchIds(ids1);
        } catch (Exception e) {
            throw new MyRuntimeException("批量删除失败！" + e.getMessage());
        }
    }

    /**
     * 为未安排课程的教师指定当前课程
     *
     * @param selectTeacher 指定的教师信息
     */
    @Override
    public void selectTeacher(SelectTeacher selectTeacher) {
        try {
            //根据课程号查询当前教师信息
            QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();
            teacherQueryWrapper.eq("c_no", selectTeacher.getNowCno());
            Teacher teacher = teacherDao.selectOne(teacherQueryWrapper);

            Teacher teacher1 = new Teacher();
            teacher1.setId(Integer.valueOf(selectTeacher.getId()));
            teacher1.setCNo(selectTeacher.getNowCno());
            //判断当前教师是否为null
            if (teacher == null) {
                teacherDao.updateById(teacher1);
            } else {
                throw new MyRuntimeException("当前课程已有教师！");
            }
        } catch (Exception e) {
            throw new MyRuntimeException("指定教师失败！" + e.getMessage());
        }
    }
}
